#include "include.h"
#include "api.h"

#if BT_FCC_TEST_EN
    #define WORK_MODE           MODE_FCC_TEST
#elif BT_BQB_RF_EN
    #define WORK_MODE           MODE_BQB_RF_BREDR
#elif LE_BQB_RF_EN
    #define WORK_MODE           MODE_BQB_RF_BLE
#else
    #define WORK_MODE           MODE_NORMAL
#endif

#if WIRELESS_CON_FULL_DUPLEX_EN
    #define D2A_CODEC           (WIRELESS_CON_CODEC_SEL | CODEC_MONO)
    #define A2D_CODEC           (WIRELESS_CON_CODEC_SEL | CODEC_STEREO)
#elif WIRELESS_SPK_TX_EN
    #define D2A_CODEC           0
    #define A2D_CODEC           (WIRELESS_CON_CODEC_SEL | CODEC_STEREO)
#else
    #define D2A_CODEC           (WIRELESS_CON_CODEC_SEL | CODEC_MONO)
    #define A2D_CODEC           0
#endif

//link
uint8_t cfg_wireless_cntl_bit       = (WIRELESS_CON_CRC_EN*0x1);
uint8_t cfg_wireless_full_duplex    = WIRELESS_CON_FULL_DUPLEX_EN;
uint8_t cfg_le_rssi_thr             = WIRELESS_CON_RSSI_THR;
uint8_t cfg_wireless_link_nb        = WIRELESS_CON_LINK_NB;
uint8_t cfg_wireless_d2a_tx_size    = WIRELESS_MIC_TX_BUFFER_SIZE;
uint8_t cfg_wireless_a2d_tx_size    = WIRELESS_SPK_TX_BUFFER_SIZE;                      //传输封包大小
uint8_t cfg_wireless_con_interval   = WIRELESS_CON_INTERVAL*WIRELESS_CON_LINK_NB;       //连接interval（V1的传输interval），单位1.25ms
uint8_t cfg_wireless_tx_interval    = WIRELESS_MIC_TX_INTERVAL;                         //V2、V3、V4的传输interval，单位1.25ms
uint8_t cfg_wireless_tx_retry       = WIRELESS_MIC_RETRY_NB;                            //V2、V3、V4的MIC的传输次数
uint8_t cfg_wireless_tx_comb_nb     = WIRELESS_MIC_COMB_NB;                             //MIC传输封包组合数量
uint8_t cfg_wireless_a2d_tx_retry   = WIRELESS_SPK_RETRY_NB;                            //V2、V3、V4的SPK的传输次数
uint8_t cfg_wireless_a2d_tx_comb_nb = WIRELESS_SPK_COMB_NB;                             //SPK传输封包组合数量
uint16_t cfg_wireless_feat          = ((WIRELESS_CON_VERS<<8)&FEAT_VERS) | (FEAT_D2A*WIRELESS_MIC_TX_EN) | (FEAT_A2D*WIRELESS_SPK_TX_EN) | (FEAT_BONDING*WIRELESS_CON_BONDING_EN) | (WIRELESS_CON_LINK_NB&0xf);
uint16_t cfg_wireless_d2a_enc_us    = WIRELESS_MIC_ENC_MAX_US + WIRELESS_MIC_DRC_DELAY + WIRELESS_MIC_ECHO_DELAY;
uint16_t cfg_wireless_d2a_dec_us    = WIRELESS_MIC_DEC_MAX_US;
uint16_t cfg_wireless_a2d_enc_us    = WIRELESS_SPK_ENC_MAX_US;
uint16_t cfg_wireless_a2d_dec_us    = WIRELESS_SPK_DEC_MAX_US;
uint8_t cfg_wireless_codec[2]       = {
    D2A_CODEC,      //D2A Codec
    A2D_CODEC,      //A2D Codec
};

//设备组队时，首先用设备名称le_name匹配，在setting中可以设置
//同时也检查设备的单/双工、编解码特性，特性不同不允许组队，参见cfg_wireless_feat和cfg_wireless_codec

//rf
uint8_t cfg_bb_rf_freq_bands        = WIRELESS_CON_FREQ_BAND; //0=2.4G, 1=2.2G, 2=2.3G, 3=2.5G
uint8_t cfg_bb_rf_def_txpwr         = 0;        //降低预置参数RF发射功率，单位0.5dbm
uint8_t cfg_bb_rf_gfsk_pwr          = 127;      //调节GFSK TXPWR，范围：90~127
uint8_t cfg_ble_page_txpwr          = 0;        //降低组队RF发射功率，单位3dbm
uint8_t cfg_ble_page_rssi_thr       = 0;        //设置组队范围rssi

//stack
uint8_t cfg_bt_work_mode            = WORK_MODE;


const char bt_local_name[] = "BT-BOX";
const char bt_local_addr[6] = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};

AT(.com_text.mic_dec)
void wireless_channel_status(u8 chidx, s8 rssi, u8 bfi, u8 chstatus)
{
    if(bfi || chstatus != 0) {
        if(rssi > -80 || (rssi > -85 && chstatus == 250)) {
            ble_con_channel_assess(chidx, false);
        }
    } else {
        ble_con_channel_assess(chidx, true);
    }
}

uint wireless_get_local_name(uint8_t *le_name)
{
    int len;
    len = strlen(xcfg_cb.le_name);

    memcpy(le_name, xcfg_cb.le_name, len);

    return len;
}

void wireless_get_local_bd_addr(u8 *addr)
{
#if BT_LOCAL_ADDR
    param_random_key_read(&addr[2]);
    addr[0] = 0x41;
    addr[1] = 0x42;
#else
    #if IODM_TEST_MODE
    if(bt_get_qr_addr(addr)){
        return;
    }
    #endif // IODM_TEST_MODE
    memcpy(addr, xcfg_cb.bt_addr, 6);
#endif
}


void bt_get_link_info_flash(void *buf, u16 addr, u16 size)
{
//    printf("bt_read: %04x,%04x, %08lx\n", addr, size, BT_CM_PAGE(addr));
    if ((addr + size) <= PAGE_DATA_SIZE) {
        cm_read(buf, BT_CM_PAGE(addr), size);
    }
//    print_r(buf, size);
}

void bt_put_link_info_flash(void *buf, u16 addr, u16 size)
{
//    printf("bt_write: %04x,%04x, %08lx\n", addr, size, BT_CM_PAGE(addr));
//    print_r(buf, size);
    if ((addr + size) <= PAGE_DATA_SIZE) {
        cm_write(buf, BT_CM_PAGE(addr), size);

    }
}

void bt_get_link_info(void *buf, u16 addr, u16 size)
{
//#if TEST_MODE_BT_INFO
//    if (bt_is_test_mode()) {
//        bt_get_link_info_ram(buf,addr,size);
//    } else
//#endif
    {
        cm_read(buf, BT_CM_PAGE(addr), size);
    }
}

void bt_put_link_info(void *buf, u16 addr, u16 size)
{
//#if TEST_MODE_BT_INFO
//    if (bt_is_test_mode()) {
//        bt_put_link_info_ram(buf,addr,size);
//    } else
//#endif
    {
        cm_write(buf, BT_CM_PAGE(addr), size);
    }
}

void bt_sync_link_info(void)
{
    cm_sync();
}


u8 con_req_addr[6];

//发送ble_connect_req消息之后，库获取连接地址的回调函数
bool ble_get_con_req_addr_cb(uint8_t *addr)
{
    memcpy(addr, con_req_addr, 6);
    return true;
}

//发送ble_scan_set_enable消息之后，底层收到数据包的回调函数
//返回值：0=错误的地址，继续扫描；1=地址正确，自动关闭扫描，可发起连接请求
bool ble_scan_rx_rep_cb(uint8_t *addr, uint8_t addr_type)
{
    printf("addr: ");
    print_r(addr, 6);

    memcpy(con_req_addr, addr, 6);

    ble_connect_req(3000);     //发消息后，通过回调函数ble_get_con_req_addr_cb获取连接地址
    return true;
}

//addr: 连接的设备地址
//timeout: 超时时间（单位ms，0xffff时一直连接不超时）
void ble_create_con_for_addr(uint8_t *addr, uint16_t timeout)
{
    memcpy(con_req_addr, addr, 6);
    ble_connect_req(timeout);   //发消息后，通过回调函数ble_get_con_req_addr_cb获取连接地址
}

//------------------------------------------------------------------------------------------
void device_init(void)
{
    wireless_con_device_init();

#if I2S_RX_AUDIO_EN
    iis_audio_in_init();
#endif
}

void adapter_init(void)
{
    wireless_con_adapter_init();
}

void wireless_init(void)
{
    //更新配置工具的设置
    cfg_bb_rf_def_txpwr = xcfg_cb.bt_rf_pwrdec;
    cfg_ble_page_txpwr = xcfg_cb.ble_rf_page_pwrdec;
    cfg_ble_page_rssi_thr = xcfg_cb.ble_page_rssi_thr;

    sys_cb.discon_reason = 0xff;
    if (wireless_role_is_adapter()) {
        adapter_init();
    } else {
        device_init();
    }

    bt_setup();
}

void wireless_adapter_init(void)
{
#if WIRELESS_SPK_TX_EN
#if ADAPTER_AUX_TX_EN
    spk_start();
#endif
#if (WIRELESS_CON_CODEC_SEL == CODEC_LC3S)
    lc3s_stereo_enc_init(WIRELESS_SPK_SAMPLE_RATE_SELECT, WIRELESS_SPK_SAMPLES_SELECT);
#endif
#endif // ADAPTER_AUX_TX_EN

#if WIRELESS_MIC_TX_EN
#if (WIRELESS_CON_CODEC_SEL == CODEC_SBC)
    sbc_dec_init(WIRELESS_MIC_SAMPLE_RATE_SELECT, WIRELESS_MIC_SAMPLES_SELECT);
#elif (WIRELESS_CON_CODEC_SEL == CODEC_ADPCM)
    adpcm_dec_init(WIRELESS_MIC_SAMPLE_RATE_SELECT, WIRELESS_MIC_SAMPLES_SELECT);
#elif (WIRELESS_CON_CODEC_SEL == CODEC_LC3S)
    lc3s_dec_init(WIRELESS_MIC_SAMPLE_RATE_SELECT,WIRELESS_MIC_SAMPLES_SELECT);
#endif

    plc_soft_init(0, WIRELESS_MIC_SAMPLES_SELECT);
    plc_soft_init(1, WIRELESS_MIC_SAMPLES_SELECT);

#if ADAPTER_MIX_DRC_EN
    mix_drc_init();
#endif
#endif // WIRELESS_MIC_TX_EN
}

void wireless_device_init(void)
{
#if WIRELESS_SPK_TX_EN
#if (WIRELESS_CON_CODEC_SEL == CODEC_LC3S)
    lc3s_stereo_dec_init(WIRELESS_SPK_SAMPLE_RATE_SELECT, WIRELESS_SPK_SAMPLES_SELECT);
#endif
#endif

#if WIRELESS_MIC_TX_EN
#if (WIRELESS_CON_CODEC_SEL == CODEC_SBC)
    sbc_enc_init(WIRELESS_MIC_SAMPLE_RATE_SELECT, 1);
#elif (WIRELESS_CON_CODEC_SEL == CODEC_ADPCM)
    adpcm_enc_init(WIRELESS_MIC_SAMPLE_RATE_SELECT, WIRELESS_MIC_SAMPLES_SELECT);
#elif (WIRELESS_CON_CODEC_SEL == CODEC_LC3S)
    lc3s_enc_init(WIRELESS_MIC_SAMPLE_RATE_SELECT, WIRELESS_MIC_SAMPLES_SELECT);
#endif
#if	!DEVICE_MIX_AUX_EN
    mic_start();
#else
    mic_mix_aux_start();
#endif
#endif // WIRELESS_MIC_TX_EN
}

void wireless_adapter_exit(u8 idx)
{
    mic_dec_reset(idx);
    plc_soft_init(idx, WIRELESS_MIC_SAMPLES_SELECT);

    wireless_cmd_reset(idx);
}

void wireless_device_exit(void)
{
#if !I2S_RX_AUDIO_EN
#if	!DEVICE_MIX_AUX_EN
    mic_stop();
#else
    mic_mix_aux_stop();
#endif
#endif
    mic_enc_reset();

    wireless_cmd_reset(0);
}
